<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
		<title>SlickGrid example 5: Collapsing</title>
		<link rel="stylesheet" href="../slick.grid.css" type="text/css" media="screen" charset="utf-8" />
        <link rel="stylesheet" href="../css/smoothness/jquery-ui-1.8.5.custom.css" type="text/css" media="screen" charset="utf-8" />
		<link rel="stylesheet" href="examples.css" type="text/css" media="screen" charset="utf-8" />
		<style>
		.cell-title {
			font-weight: bold;
		}

		.cell-effort-driven {
			text-align: center;
		}

		.toggle {
			height: 9px;
			width: 9px;
			display: inline-block;
		}

		.toggle.expand {
			background: url(../images/expand.gif) no-repeat center center;
		}

		.toggle.collapse {
			background: url(../images/collapse.gif) no-repeat center center;
		}

	</style>
	</head>
	<body>
		<table width="100%">
		<tr>
			<td valign="top" width="50%">
				<div style="border:1px solid gray;background:wheat;padding:6px;">
					<label>Show tasks with % at least: </label>
					<div style="padding:4px;">
						<div style="width:100px;" id="pcSlider"></div>
					</div>
					<br/>
					<label>And title including:</label>
					<input type=text id="txtSearch">
				</div>
				<br/>
				<div id="myGrid" style="width:600px;height:500px;"></div>
			</td>
			<td valign="top">
				<h2>Demonstrates:</h2>
				<ul>
					<li>implementing expand/collapse as a filter for DataView</li>
				</ul>
			</td>
		</tr>
		</table>

		<script language="JavaScript" src="../lib/firebugx.js"></script>

		<script language="JavaScript" src="../lib/jquery-1.4.3.min.js"></script>
		<script language="JavaScript" src="../lib/jquery-ui-1.8.5.custom.min.js"></script>
		<script language="JavaScript" src="../lib/jquery.event.drag-2.0.min.js"></script>

		<script language="JavaScript" src="../slick.editors.js"></script>
		<script language="JavaScript" src="../slick.grid.js"></script>
		<script language="JavaScript" src="../slick.model.js"></script>

		<script>
		function requiredFieldValidator(value) {
			if (value == null || value == undefined || !value.length)
				return {valid:false, msg:"This is a required field"};
			else
				return {valid:true, msg:null};
		}


		var TaskNameFormatter = function(row, cell, value, columnDef, dataContext) {
		    var spacer = "<span style='display:inline-block;height:1px;width:" + (15 * dataContext["indent"]) + "px'></span>";
		    var idx = dataView.getIdxById(dataContext.id);
			if (data[idx+1] && data[idx+1].indent > data[idx].indent) {
				if (dataContext._collapsed)
					return spacer + " <span class='toggle expand'></span>&nbsp;" + value;
				else
					return spacer + " <span class='toggle collapse'></span>&nbsp;" + value;
			}
			else
				return spacer + " <span class='toggle'></span>&nbsp;" + value;
		};

		var dataView;
		var grid;

		var data = [];

		var columns = [
			{id:"title", name:"Title", field:"title", width:220, cssClass:"cell-title", formatter:TaskNameFormatter, editor:TextCellEditor, validator:requiredFieldValidator},
			{id:"duration", name:"Duration", field:"duration", editor:TextCellEditor},
			{id:"%", name:"% Complete", field:"percentComplete", width:80, resizable:false, formatter:GraphicalPercentCompleteCellFormatter, editor:PercentCompleteCellEditor},
			{id:"start", name:"Start", field:"start", minWidth:60, editor:DateCellEditor},
			{id:"finish", name:"Finish", field:"finish", minWidth:60, editor:DateCellEditor},
			{id:"effort-driven", name:"Effort Driven", width:80, minWidth:20, maxWidth:80, cssClass:"cell-effort-driven", field:"effortDriven", formatter:BoolCellFormatter, editor:YesNoCheckboxCellEditor, cannotTriggerInsert:true}
		];

		var options = {
			editable: true,
			enableAddRow: true,
			enableCellNavigation: true,
			asyncEditorLoading: false
		};


		var percentCompleteThreshold = 0;
		var searchString = "";

		function myFilter(item) {
			if (item["percentComplete"] < percentCompleteThreshold)
				return false;

			if (searchString != "" && item["title"].indexOf(searchString) == -1)
				return false;

			var idx = dataView.getIdxById(item.id);

			if (item.parent != null) {
				var parent = data[item.parent];

				while (parent) {
					if (parent._collapsed || (parent["percentComplete"] < percentCompleteThreshold) || (searchString != "" && parent["title"].indexOf(searchString) == -1) )
						return false;

					parent = data[parent.parent];
				}
			}

			return true;
		}

		function percentCompleteSort(a,b) {
			return a["percentComplete"] - b["percentComplete"];
		}

		function addItem(newItem,columnDef) {
			var item = {"id": "new_" + (Math.round(Math.random()*10000)), "indent":0, "title":"New task", "duration":"1 day", "percentComplete":0, "start":"01/01/2009", "finish":"01/01/2009", "effortDriven":false};
			$.extend(item,newItem);
			dataView.addItem(item);
		}


		$(function()
		{
			var indent = 0;
			var parents = [];

			// prepare the data
			for (var i=0; i<1000; i++) {
				var d = (data[i] = {});
				var parent = null;

				if (Math.random() > 0.8) {
					indent++;
					parent = i - 1;
					parents.push(parent);
				}
				else if (Math.random() < 0.3 && indent > 0) {
					indent--;
					parent = parents.pop();
				}
				else if (parents.length > 0)
					parent = parents[parents.length-1];

				if (indent == 0)
					parent = null;

				d["id"] = "id_" + i;
				d["indent"] = indent;
				d["parent"] = parent;
				d["title"] = "Task " + i;
				d["duration"] = "5 days";
				d["percentComplete"] = Math.round(Math.random() * 100);
				d["start"] = "01/01/2009";
				d["finish"] = "01/05/2009";
				d["effortDriven"] = (i % 5 == 0);
			}


			// initialize the model
			dataView = new Slick.Data.DataView();
			dataView.beginUpdate();
			dataView.setItems(data);
			dataView.setFilter(myFilter);
			dataView.endUpdate();


			// initialize the grid
			grid = new Slick.Grid($("#myGrid"), dataView.rows, columns, options);

            grid.onCellChange = function(row,col,item) {
                dataView.updateItem(item.id,item);
            };
            
			grid.onAddNewRow = addItem;

			grid.onClick = function(e, row, cell) {
                if ($(e.target).hasClass("toggle")) {

                    var item = dataView.rows[row];
                    if (item) {
                        if (!item._collapsed)
                            item._collapsed = true;
                        else
                            item._collapsed = false;

                        dataView.updateItem(item.id, item);
                    }

                    return true;
                }

                return false;
            };


			// wire up model events to drive the grid
			dataView.onRowCountChanged.subscribe(function(args) {
				grid.updateRowCount();
                grid.render();
			});

			dataView.onRowsChanged.subscribe(function(rows) {
				grid.removeRows(rows);
				grid.render();
			});


			var h_runfilters = null;

			// wire up the slider to apply the filter to the model
			$("#pcSlider").slider({
				"range":	"min",
				"slide":	function(event,ui) {
                    Slick.GlobalEditorLock.cancelCurrentEdit();

					if (percentCompleteThreshold != ui.value)
					{
						window.clearTimeout(h_runfilters);
						h_runfilters = window.setTimeout(dataView.refresh, 10);
						percentCompleteThreshold = ui.value;
					}
				}
			});


			// wire up the search textbox to apply the filter to the model
			$("#txtSearch").keyup(function(e) {
                Slick.GlobalEditorLock.cancelCurrentEdit();

				// clear on Esc
				if (e.which == 27)
					this.value = "";

				searchString = this.value;
				dataView.refresh();
			})
		})

		</script>

	</body>
</html>
